package com.metasoft.flex.service {
	
	import _2005.extended.metadata.tva.TVAMainDocument;
	import _2005.profile.tva.ModifyDocument;
	import _2005.transport.tva.BinaryPredicateType;
	import _2005.transport.tva.DeleteDataDocument;
	import _2005.transport.tva.GetDataDocument;
	import _2005.transport.tva.PredicateBagType;
	
	import com.metasoft.flex.MetasoftULC;
	import com.metasoft.flex.dto.ProfileInfo;
	import com.metasoft.flex.util.MetasoftHelper;
	
	import flash.net.SharedObject;
	
	import mx.controls.Alert;
	import mx.messaging.Channel;
	import mx.messaging.ChannelSet;
	import mx.messaging.channels.AMFChannel;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.mxml.RemoteObject;
	
				
	public class MetasoftService {
		
//		private const wsdl:String = MetasoftULC.ContextPath + "/services/MetasoftTVAService?wsdl";
//		private var metasoftWS:WebService;
//		private var wsLoaded:Boolean;
		
    	public function MetasoftService():void {
    		//initialize();
    	}
    	
		/**
		 * Initializes the webservice withe default settings.
		 *
		 */
		/*protected function initialize():void {

			if (metasoftWS == null) {
				wsLoaded = true;
				initLogging();
				metasoftWS = new WebService();
				metasoftWS.useProxy = false;
				//metasoftWS.concurrency = "single";
				metasoftWS.wsdl = wsdl;
				metasoftWS.addEventListener("fault", faultHandler);
				//metasoftWS.addEventListener("load", wsdlLoaded);
				metasoftWS.loadWSDL();
			}
		}
		
		private function wsdlLoaded(event:LoadEvent):void {
			metasoftWS.removeEventListener("load", wsdlLoaded);
			wsLoaded = true;
		}
		
		private function initLogging():void {
            // Create a target.
            var logTarget:TraceTarget = new TraceTarget();

            // Log only messages for the classes in the mx.rpc.* and 
            // mx.messaging packages.
            logTarget.filters=["mx.rpc.*","mx.messaging.*"];

            // Log all log levels.
            logTarget.level = LogEventLevel.ALL;

            // Add date, time, category, and log level to the output.
            logTarget.includeDate = true;
            logTarget.includeTime = true;
            logTarget.includeCategory = true;
            logTarget.includeLevel = true;

            // Begin logging.
            Log.addTarget(logTarget);
        }*/
		
		public function getRemoteObject() : RemoteObject {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = new mx.rpc.remoting.mxml.RemoteObject();
			
			var cs:ChannelSet = new ChannelSet();
            var customChannel:Channel = new AMFChannel(MetasoftULC.ChannelDef, MetasoftULC.ChannelURL);
            cs.addChannel(customChannel);
            remoteObj.channelSet = cs;
			remoteObj.destination = MetasoftULC.ChannelDestination;
			remoteObj.addEventListener(FaultEvent.FAULT,faultHandler);
			remoteObj.showBusyCursor = true;
			return remoteObj;			
		}
		
		public function getRemoteUtilObject() : RemoteObject {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = new mx.rpc.remoting.mxml.RemoteObject();
			
			var cs:ChannelSet = new ChannelSet();
            var customChannel:Channel = new AMFChannel(MetasoftULC.ChannelDef, MetasoftULC.ChannelURL);
            cs.addChannel(customChannel);
            remoteObj.channelSet = cs;
			remoteObj.destination = MetasoftULC.AdminChannelDestination;
			remoteObj.addEventListener(FaultEvent.FAULT,faultHandler);
			remoteObj.showBusyCursor = true;
			return remoteObj;			
		}



		/**
		 * Method to handle the error occuring in the service
		 * 
		 */
		public function faultHandler(event:FaultEvent):void {
            Alert.show(event.fault.faultString);
        }

		/**
		 * Invokes submitData tva service
		 *
		 * @param uploadDataContent - Input Preference XML content.
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function uploadPersonalData(regProfileInfo : ProfileInfo, callBack:Function):void {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.uploadData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.uploadData(MetasoftHelper.getUploadDataDocument(regProfileInfo));
		}

		private function getPredicateeBag(getData : Object):Array {

			if (getData != null &&
				getData.getData != null &&
				getData.getData.queryConstraints != null &&
				getData.getData.queryConstraints.predicateBag != null &&
				getData.getData.queryConstraints.predicateBag.predicateBagArray != null &&
				getData.getData.queryConstraints.predicateBag.predicateBagArray.length > 0) {

				return getData.getData.queryConstraints.predicateBag.predicateBagArray;
			} else if (getData != null &&
				getData.getData != null &&
				getData.getData.queryConstraints != null &&
				getData.getData.queryConstraints.predicateBag != null) {

				var predicateBagArray : Array = new Array();
				predicateBagArray.push(getData.getData.queryConstraints.predicateBag);
				return predicateBagArray;
			}
			return null;
		}

		private function getBinaryPredicate(getData : Object):BinaryPredicateType {

			if (getData != null &&
				getData.getData != null &&
				getData.getData.queryConstraints != null &&
				getData.getData.queryConstraints.predicateBag != null &&
				getData.getData.queryConstraints.predicateBag.binaryPredicateArray != null &&
				getData.getData.queryConstraints.predicateBag.binaryPredicateArray [0] != null) {

				return getData.getData.queryConstraints.predicateBag.binaryPredicateArray[0] as BinaryPredicateType;
			}
			return null;
		}
		
	    /**
	     * Retrieves the search results based on the search value
	     */
		public function getSearchResult(callBack:Function, searchVal:String, preferenceSelected : Boolean):void {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			var getData : GetDataDocument = null;
			if (preferenceSelected) {

				getData = MetasoftHelper.getKeywordCriteria(searchVal);
				getData = MetasoftHelper.addUserPreference(getPredicateeBag(getData), null);
			} else {
				getData = MetasoftHelper.getKeywordCriteria(searchVal);
			}
			remoteObj.getData(getData);
		}

		public function getRatingSearchResult(callBack:Function, searchVals:Array, preferenceSelected : Boolean):void {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			var getData : GetDataDocument = null;
			if (preferenceSelected) {

				getData = MetasoftHelper.getRatingCriteria(searchVals);
				getData = MetasoftHelper.addUserPreference(getPredicateeBag(getData), getBinaryPredicate(getData));
			} else {
				getData = MetasoftHelper.getRatingCriteria(searchVals);
			}
			remoteObj.getData(getData);
		}

		/**
	     * Retrieves the search results based on the search value
	     */
		public function getCreditSearchResult(callBack:Function, searchVal:String, preferenceSelected : Boolean):void {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			var getData : GetDataDocument = null;
			if (preferenceSelected) {

				getData = MetasoftHelper.getCreditCriteria(searchVal);
				getData = MetasoftHelper.addUserPreference(getPredicateeBag(getData), null);
			} else {
				getData = MetasoftHelper.getCreditCriteria(searchVal);
			}
			remoteObj.getData(getData);
		}

		/**
	     * Retrieves the search results based on the search value
	     */
		public function getCategorySearchResult(callBack:Function, searchVal:String, preferenceSelected : Boolean):void {

			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			var getData : GetDataDocument = null;
			if (preferenceSelected) {

				getData = MetasoftHelper.getCategoryCriteria(searchVal);
				getData = MetasoftHelper.addUserPreference(getPredicateeBag(getData), null);
			} else {
				getData = MetasoftHelper.getCategoryCriteria(searchVal);
			}
			remoteObj.getData(getData);
		}

		/**
		 * Invokes getData tva service
		 *
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function get_Data(callBack:Function):void {

			var so:SharedObject = SharedObject.getLocal(MetasoftULC.LoggedInUser);
			if (so.data.userId == null) {
				return;
			}
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.getData(MetasoftHelper.getGetDataDocument(so));
		}
		
		/**
		 * Invokes submitData tva service
		 *
		 * @param uploadDataContent - Input Preference XML content.
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function getPersonalData(userName:String, password:String, callBack:Function):void {
                
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.queryData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.queryData(MetasoftHelper.getPersonalProfile(userName,password));
		}

		/**
		 * Invokes modifyData tva service
		 *
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function modifyPersonalData(profileInfo:ProfileInfo,callBack:Function):void {
			
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.modifyData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.modifyData(MetasoftHelper.modifyPersonalProfile(profileInfo));
		}

		/**
		 * Invokes modifyData tva service for updating the UsageHistory
		 * Collecting the user related infomation in the background
		 * 
		 * @param profileInfo
		 */
		public function modifyUsageHistory(profileInfo:ProfileInfo):void {
			
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.modifyData(MetasoftHelper.modifyUsageHistory(profileInfo));
		}

		/**
		 * Invokes submitData tva service 
		 * 
		 * @param profileInfo
		 */
		public function submitData(tvaMainDoc : TVAMainDocument, callBack:Function):void {
			
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.submitData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.submitData(tvaMainDoc);
		}
		
		
		/** Invokes deleteData 
		 * 
		 * @param DeleteDataDocument, Function
		 */
		public function deleteData(deleteDataDoc : DeleteDataDocument, callBack:Function):void {
			
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.deleteData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.deleteData(deleteDataDoc);
		}

		/**
		 * Invokes getData tva service
		 *
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function getData(getdataQuery:GetDataDocument, callBack:Function):void {

			if (getdataQuery == null) {
				return;
			}
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.getData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.getData(getdataQuery);
		}
		
		/**
		 * Invokes modifyData tva service
		 *
		 * @param tvaMainDoc - Input ModifyDocument XML content.
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function modifyData(modifyDoc:ModifyDocument, callBack:Function):void {
			
			if (modifyDoc == null) {
				return;
			}
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.modifyData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.modifyData(modifyDoc);
		}
		
		/**
		 * Invokes queryData  tva service for PackageTable info retrieval
		 *
		 * @param uploadDataContent - Input Preference XML content.
		 * @param callBack The function to be notified when the RPC is complete
		 */
		public function queryPackageData(userName:String,callBack:Function):void {
                
			var remoteObj:mx.rpc.remoting.mxml.RemoteObject = getRemoteObject();
			remoteObj.queryData.addEventListener(ResultEvent.RESULT,callBack);
			remoteObj.queryData(MetasoftHelper.getPackageQueryDocument(userName));
		}
	}
}